/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package GoMail;
import java.text.ParseException;
import message.*;
import DlinkedList.DNode;
import DlinkedList.MyDList;
import Queue.MyQueue;
import SingleLinkedList.SingleNode;
import java.util.*;
import account.Account;
import folders2.*;
import java.io.*;
import java.text.SimpleDateFormat;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
import sorting_searching.SData;
import stack.MyStack;

/**
 *
 * @author Administrator
 */
public class MailUserOperations implements MailUserOperationsInterface
{
    private MailUser user;              //reference to user folders and account
    private MyDList message;            //To load message from any folder to it
    private MyQueue sendMessage;        //use it in sending messages to multiple users
    private MyDList filterList;     //contains all filter conditions in subject or sender and direction folder name to this messages
    private MyDList contactsList;   //contains all user contacts information
    private Object ref;     //i use it to hold the index of last message loaded in message doubly linked list

    /**
     * Constructor to make MailUserOperations
     * @param parent parent folder to user folder (root folder in our case)
     * @param c user account which made it when new user want to sign in mail
     * @throws java.io.IOException
     */
    public MailUserOperations(File parent,Account c)throws IOException
    {
        user = new MailUser(parent,c);
        message = new MyDList();
        sendMessage = new MyQueue();
        filterList = new MyDList();
        contactsList = new MyDList();
        ref = new Object();
        c.writeAccountData(user.getFolders().getMyDir().getMyFile());
    }
    /**
     * Defualt constructor to initailize instance variables (new user without any data about him)
     */
    public MailUserOperations()
    {
        filterList = new MyDList();
        contactsList = new MyDList();
        ref = new Object();
        user = new MailUser();
        message = new MyDList();
        sendMessage = new MyQueue();
    }
    /**
     * get user contact list
     * @return doubly linked list contains all users contacts and thier mails
     */
    public MyDList getContactsList()
    {
        return contactsList;
    }
    /**
     * set user contact list by change old one by new list of contacts
     * @param contactsList new doubly linked list of contacts
     */
    public void setContactsList(MyDList contactsList)
    {
        this.contactsList = contactsList;
    }
    /**
     * method to get filters user list
     * @return
     */
    public MyDList getFilterList()
    {
        return filterList;
    }
    /**
     * set filter list
     * @param filterList new filter list
     */
    public void setFilterList(MyDList filterList)
    {
        this.filterList = filterList;
    }
    /**
     * get object ref which contains the index of last messsage loaded in the list
     * @return
     */
    public Object getRef()
    {
        return ref;
    }
    /**
     * set index of last message loaded
     * @param ref new index
     */
    public void setRef(Object ref)
    {
        this.ref = ref;
    }

    /**
     * get list that contains ten message that will be loaded from any user folder
     * @return list of messages (doubliy linked list)
     */
    public MyDList getMessage()
    {
        return message;
    }
    /**
     * set messages list
     * @param message new messages list
     */
    public void setMessage(MyDList message)
    {
        this.message = message;
    }
    /**
     * get list that contains all sent messages(nearly i don't use it)
     * @return queue list of sent messages
     */
    public MyQueue getSendMessage()
    {
        return sendMessage;
    }
    /**
     * set queue to new queue with new messages
     * @param sendMessage new queue
     */
    public void setSendMessage(MyQueue sendMessage)
    {
        this.sendMessage = sendMessage;
    }
    /**
     * get user data (folders and account) from this object
     * @return MailUser object
     */
    public MailUser getUser()
    {
        return user;
    }
    /**
     * set user data (folders and account) from this object
     * @param user
     */
    public void setUser(MailUser user)
    {
        this.user = user;
    }
    /**
     * this method i use it to loading user data(account and reference to user folders)
     * after verfying from this user is exist in our server from users file
     * @param userId  userName
     * @param root  root folder which contains all users folders
     * @throws java.io.IOException
     */
    public void findUser(String userId,ProjectFile root)throws IOException
    {
        ProjectFile u = root.search(userId);
        UserFolders2 userF = new UserFolders2(u);
        /*userF.setCustomFolders(new MyDList());*/
        Account c = new Account();
        userF.setUserName(c.getUserName());
        File[]children = u.getMyFile().listFiles();
        children = removeHiddenFiles(children);
        for(int i=0;i<children.length;i++)
        {
            setFoldersRef(children[i],userF,c);
        }
        MailUser m = new MailUser();
        m.setUserAccount(c);
        m.setFolders(userF);
        this.setUser(m);
    }
    /**
     * this method is called by findUser to set references to user folders &
     * account information from account file
     * and filter informations and  contact informations
     * @param f main user folder that contians all folders and files about this user
     * @param u Object of UserFolder to set its references and then give it to the MailuserOperations in privios method
     * @param c user account to st its data(first name ,lastname ...............etc)
     * @throws java.io.IOException
     */
    public void setFoldersRef(File f, UserFolders2 u, Account c)throws IOException
    {
        if(f.getName().equalsIgnoreCase("Inbox"))
        {
            u.setInbox(new ProjectFile(f));
        }
        else if(f.getName().equalsIgnoreCase("Trash"))
        {
            u.setTrash(new ProjectFile(f));
        }
        else if(f.getName().equalsIgnoreCase("sent"))
        {
            u.setSent(new ProjectFile(f));
        }
        else if(f.getName().equalsIgnoreCase("draft"))
        {
            u.setDraft(new ProjectFile(f));
        }
        else if(f.getName().equalsIgnoreCase("spam"))
        {
            u.setSpam(new ProjectFile(f));
        }
        else if(f.getName().equalsIgnoreCase("contactsFile"))
        {
            u.setContactsFile(new ProjectFile(f));
            this.readContactData(f);
        }
        else if(f.getName().equalsIgnoreCase("Filter"))
        {
            u.setFilter(new ProjectFile(f));
            this.readFilterData(f);
        }
        else if(f.isDirectory())
        {
            /*if(u.getCustomFolders()==null)
            {
            u.setCustomFolders(new MyDList());
            }*/
           u.getCustomFolders().add(new ProjectFile(f));
        }
        else
        {
            c.readAccountData(f);
        }
    }
    /*                    //////// i don't use this method i use another easer one
    public void deleteMessage(String name, int key) {
        JFileChooser chooser = new JFileChooser();
        FileSystemView v = chooser.getFileSystemView();  //use it to get child folder by name directly
        ProjectFile f;
        switch (key) {
            case 0: //Message in Inbox
            {
                f = new ProjectFile(v.getChild(user.getFolders().getInbox().getMyFile(), name));
                f.deleteFile();
            }
            case 1: //Trash
            {
                f = new ProjectFile(v.getChild(user.getFolders().getTrash().getMyFile(), name));
                f.deleteFile();
            }
            case 2: //sent folder
            {
                f = new ProjectFile(v.getChild(user.getFolders().getSent().getMyFile(), name));
                f.deleteFile();
            }
            case 3: //Draft
            {
                f = new ProjectFile(v.getChild(user.getFolders().getDraft().getMyFile(), name));
                f.deleteFile();
            }
            case 4: //Spam
            {
                f = new ProjectFile(v.getChild(user.getFolders().getSpam().getMyFile(), name));
                f.deleteFile();
            }
            default: // in any one of custom Folders
            {
                MyDList list = user.getFolders().getCustomFolders();
                int i = 0;
                DNode u = list.getHeader();
                boolean found = false;
                while ((i < list.getSize()) && !found) {
                    i++;
                    u = u.getNext();
                    f = (ProjectFile) u.getData();
                    File child = v.getChild(f.getMyFile(), name);
                    if (child.exists()) {
                        ProjectFile m = new ProjectFile(child);
                        m.deleteFile();
                        found = true;
                    }
                }
            }
        }
    }
    */
    /**
     * I use this method to delete any message in any folder
     * and transfer deleted one to trash folder
     * @param mess message which will be deleted
     * @throws java.io.IOException
     */
    public void deleteMessage(MessageFolder mess) throws IOException
    {
        ProjectFile m = new ProjectFile(user.getFolders().getTrash().getMyFile(),mess.getSms().getName());
        m.getMyFile().mkdir();
        m.copy(mess.getMessFolder().getMyFile());
        mess.getMessFolder().deleteFile();
    }
       //Idon't use this method in any thing
    public void moveMessageTo(ProjectFile to,ProjectFile source,String messageName)throws IOException
    {
        ProjectFile f = source.search(messageName);
        to.copy(f.getMyFile());
        f.deleteFile();
    }
    //defualt move messages to inbox unless there are filters in message subject or sender
    /**
     * I use this method to transfer send messages to this user from temp folder to user folder
     * during tranfer sent messages method checks if there are any filters in this message
     * if there are any filters message is transfered to thespecified folder to that filter
     * else message tensfer to user inbox
     * @param source temp folder
     * @param messageCount number of messages sent to this user
     * @throws java.io.IOException
     */
    public void  moveMessageToUserFolder(ProjectFile source, int messageCount) throws IOException
    {
        boolean match = false;
        int index = 0;
        int i =0;
        if(messageCount != 0)
        {
            File[]tempMessages = source.getMyFile().listFiles();
            tempMessages = removeHiddenFiles(tempMessages);
            MessageFolder[] messagesFolders = new MessageFolder[tempMessages.length];
            for(int a =0; a< messagesFolders.length;a++)
            {
                messagesFolders[a] = new MessageFolder();
                messagesFolders[a].findMessageComponent(tempMessages[a]);
            }
            SData s = new SData(messagesFolders,user.getUserAccount().getUserName());
            s.setCompareKey(11);
            s.sortList();
            Object o = s.binSearch();       //this object of type file
            if(o != null)
            {
                int IndexOfSentMessage = (Integer)o;
                MessageFolder sentMessage = (MessageFolder)s.getData()[IndexOfSentMessage];
                if(! (filterBySubject(sentMessage) == 1 || filterBySender(sentMessage) == 1))
                {
                    //if there are no filters in this message then message by defualt trnsfer to inbox
                    ProjectFile m = new ProjectFile(user.getFolders().getInbox().getMyFile(),sentMessage.getSms().getName());
                    m.getMyFile().mkdir();
                    m.copy(sentMessage.getMessFolder().getMyFile());
                    sentMessage.getMessFolder().deleteFile();
                    i++;
                }
                else
                {
                    i++;
                }
                if(messageCount != 1)
                {
                    index = IndexOfSentMessage-1;
                    while(i < messageCount && IndexOfSentMessage >= 0)
                    {
                        if(IndexOfSentMessage > 0)
                        {
                            do
                            {

                                MessageFolder u = (MessageFolder)s.getData()[index];
                                String messageReceiver = u.getSms().getReceiver().substring(0,u.getSms().getReceiver().indexOf("@"));
                                if(messageReceiver.equalsIgnoreCase(user.getUserAccount().getUserName()))
                                {
                                    MessageFolder sms = (MessageFolder)s.getData()[index];
                                    if(! (filterBySubject(sms) == 1 || filterBySender(sms) == 1))
                                    {
                                        ProjectFile messagePlace = new ProjectFile(user.getFolders().getInbox().getMyFile(),sms.getSms().getName());
                                        messagePlace.getMyFile().mkdir();
                                        messagePlace.copy(sms.getMessFolder().getMyFile());
                                        sms.getMessFolder().deleteFile();
                                    }
                                    match = true;
                                    i++;
                                }
                                else
                                {
                                    match = false;
                                }
                        }while(match && index > 0 && i < messageCount);
                        
                        }
                        match = true;
                        index = IndexOfSentMessage+1;
                        if(IndexOfSentMessage < s.getData().length && match)
                        {
                            do
                            {
                                MessageFolder u = (MessageFolder)s.getData()[index];
                                String messageReceiver = u.getSms().getReceiver().substring(0,u.getSms().getReceiver().indexOf("@"));
                                if(messageReceiver.equalsIgnoreCase(user.getUserAccount().getUserName()))
                                {
                                    MessageFolder sms = (MessageFolder)s.getData()[index];
                                    if(! (filterBySubject(sms) == 1 || filterBySender(sms) == 1))
                                    {
                                        ProjectFile messagePlace = new ProjectFile(user.getFolders().getInbox().getMyFile(),sms.getSms().getName());
                                        messagePlace.getMyFile().mkdir();
                                        messagePlace.copy(sms.getMessFolder().getMyFile());
                                        sms.getMessFolder().deleteFile();
                                    }
                                    match = true;
                                    i++;
                                }
                                else
                                {
                                    match = false;
                                }
                            }while(match && index < s.getData().length && i < messageCount);
                        }
                    }
                }
            }
        }

    }


    /*////////////i can use it in the beganing of program
    public int findSentMessages(UserFileOperation2 mailUsers, File temp)throws IOException
    {
    int count = mailUsers.mailExist(user.getUserAccount().getUserName(),user.getUserAccount().getPassword());
    if(count != 0)
    {

    int i = 0;
    while(i < count)
    {
    File[] messages = temp.listFiles();
    SData s = new SData(messages, user.getUserAccount().getUserName());
    s.setCompareKey(7);
    s.sortList();
    Object o = s.binSearch();
    ProjectFile sms = new ProjectFile((File)o);
    MessageFolder m = new MessageFolder();
    m.findMessageComponent(sms.getMyFile());
    if(filterBySubject(m) == 0 || filterBySubject(m) == 0)
    {
    user.getFolders().getMyDir().copy(sms.getMyFile());
    }
    sms.deleteFile();
    i++;
    }
    }
    return count;
    }*/
    /**
     * this method is used to add new contact to user
     * @param c new contact
     */
    public void addContact(Contacts c)
    {
        contactsList.add(c);
    }
    /**
     * this method is used to search for contact with specified name
     * if this contact is exist in user contact list then method return contact node
     * in the list to make me use it in other things like in findContact(String name)
     * and  deleteContact(String contactName)
     * @param name contact name
     * @return returns DNode which contains contact else returns null
     */
    private DNode searchContacts(String name)
    {
        SData find = new SData();
        find.copyList(contactsList, name);
        find.setCompareKey(4);
        find.sortList();
        DNode v = (DNode)find.binSearch();
        return v;
    }
    /**
     * this method is used to find contact by the holping of searchContacts(String name) method
     * @param name contact name
     * @return returns contact which contains contact informations else returns null
     */
    public Contacts findContact(String name)
    {
        DNode v = (DNode)searchContacts(name);
        if( v == null)
            return null;
        Contacts c = (Contacts)v.getData();
        return c;       //return null if not found
    }

    /**
     * this method is used to delete contact by the holping of searchContacts(String name) method
     * @param contactName contact name
     */
    public void deleteContact(String contactName)
    {
        DNode u = searchContacts(contactName);
        DNode v = u.getPrev();
        DNode w = u.getNext();
        v.setNext(w);
        w.setPrev(v);
        u.setNext(null);
        u.setPrev(null);
        u.setData(null);
        contactsList.setSize(contactsList.getSize()-1);
    }
                    /////////////////////create custom folders
    /**
     * this method is used to create new custom folder in user folder
     * @param FolderName new custom folder name
     */
    public void createFolder(String FolderName)
    {
        user.getFolders().createCustomFolder(FolderName);
    }
    /**
     * this method is used to delete any folder from user folders
     * (in our case we use it to delete cutom folder)
     * @param folderName folder name
     */
    public void deleteFolder(String folderName)
    {
        JFileChooser chooser = new JFileChooser();
        FileSystemView v = chooser.getFileSystemView();
        File u = v.getChild(user.getFolders().getMyDir().getMyFile(), folderName);
        ProjectFile w = new ProjectFile(u);
        w.deleteFile();
    }
        //?????????????????????????????????????????????????oooooooooooooooooooo
    /**
     * This method is used to rename any folder
     * @param oldName old name of this folder
     * @param newName new name
     * @throws java.io.IOException
     */
    public void renameFolder(String oldName,String newName) throws IOException
    {
        JFileChooser chooser = new JFileChooser();
        FileSystemView v = chooser.getFileSystemView();
        ProjectFile old = new ProjectFile(v.getChild(user.getFolders().getMyDir().getMyFile(), oldName));
        ProjectFile newFile = new ProjectFile(user.getFolders().getMyDir().getMyFile(),newName);
        newFile.copy(old.getMyFile());
        old.deleteFile();
    }
                    //////////////load Mails
    /**
    public void loadMailsFormFolder(String folderName, int key)
    {
        JFileChooser chooser = new JFileChooser();
        FileSystemView v = chooser.getFileSystemView();
        SData s = new SData();
        File messageFolder = v.getChild(user.getFolders().getMyDir().getMyFile(), folderName);
        if(messageFolder.exists())
        {
            File[] allMessages = messageFolder.listFiles();
            s.setData(allMessages);
            s.setCompareKey(5);
            s.sortList();
            switch(key)
            {
                /**
                 * if key = 0 read first message up to 10 or up to number of messages
                 * if key = 1 read next 10 messages
                 * if key = 2 read previous 10 messages
                 */
                /**case 0 :
                {
                    int i = 0;
                    while(i < s.getData().length && i < 10)
                    {
                        message.add(s.getData()[i]);
                        i++;
                    }
                    ref = i;
                };break;
                case 1:
                {
                    int i = (Integer)ref;
                    message.clear();
                    while(i<s.getData().length && i<10)
                    {
                        message.add(s.getData()[i]);
                    }
                    ref = i;
                };break;
                case 2:
                {
                    int i = (Integer)ref;
                    message.clear();
                    int c = 0;
                    while(i < s.getData().length && i >=0 && c < 10)
                    {
                        message.add(s.getData()[c]);
                        c++;
                        i--;
                    }
                    ref = i;
                };break;
            }
        }
    }
    **/
    /**
     * This method is used to remove hidden files which are loaded with user folder and unwanted to use
     * @param filesArray array of user files and folders
     * @return new array that doesn't contains any hidden folder
     */
    public File[] removeHiddenFiles(File[]filesArray)
    {
        if(filesArray.length != 0)
        {
            MyDList newFiles = new MyDList();
            for(int i=0;i<filesArray.length;i++)
            {
                if(! filesArray[i].isHidden())
                {
                    newFiles.add(filesArray[i]);
                }
            }
            File[]allNonHiddenFiles = new File[newFiles.getSize()];
            DNode u = newFiles.getHeader();
            for(int i=0;i<newFiles.getSize();i++)
            {
                u = u.getNext();
                allNonHiddenFiles[i] = (File)u.getData();
            }
            return allNonHiddenFiles;
        }
        else
            return filesArray;          //return same arrray if it is empty
    }
    /**
     * This method is used to load message folder from any folder
     * and put them into messageFolder[] array
     * @param folderName fodler name which we want to read messages from it
     * @return MessageFolder[] that contains all files if folder name is wrong
     * i.e folder doesn't exist returns null
     * @throws java.io.IOException
     */
    public MessageFolder[] loadAllMailsFormFolder(String folderName) throws IOException
    {
        JFileChooser chooser = new JFileChooser();
        FileSystemView v = chooser.getFileSystemView();
        File messageFolder = v.getChild(user.getFolders().getMyDir().getMyFile(), folderName);
        if(messageFolder.exists())
        {
            File[] allMessages = messageFolder.listFiles();
            allMessages = removeHiddenFiles(allMessages);
            MessageFolder[] sms = new MessageFolder[allMessages.length];
            for(int i=0; i< sms.length;i++)
            {
                sms[i] = new MessageFolder();
                sms[i].findMessageComponent(allMessages[i]);
            }
            return sms;
        }
        else
            return null;
    }
    /**
     * This method is used to load messages from array of messages that contains all message
     * to message doubly linked list load only 10 messages
     * @param all array that contains all messages of folder
     * that returns from loadAllMailsFormFolder(String folderName)
     * @param key key to determine which ten message will be read
     * when key = 0 read first ten message
     * key = 1 read next ten messages
     * key  = 2 read previous ten messages
     */
    public void loadMessagesIntoList(MessageFolder[] all, int key)
    {
            SData s = new SData();
            s.setData(all);
            s.setCompareKey(5);
            s.sortList();
            switch(key)
            {
                /**
                 * if key = 0 read first message up to 10 or up to number of messages
                 * if key = 1 read next 10 messages
                 * if key = 2 read previous 10 messages
                 */
                case 0 :
                {
                    if(message.getSize() != 0)
                        message.clear();
                    int i = 0;
                    while(i < s.getData().length && i < 10)
                    {
                        message.add(s.getData()[i]);
                        i++;
                    }
                    ref = i;
                };break;
                case 1:
                {
                    int i = (Integer)ref;
                    message.clear();
                    int c = 0;
                    while(i < s.getData().length && c<10)
                    {
                        message.add(s.getData()[i]);
                        i++;
                        c++;
                    }
                    ref = i;
                };break;
                case 2:
                {
                    int i = (Integer)ref;
                    message.clear();
                    int c = i - 11;
                    if(c < 0)
                        c = 0;
                    while(i <= s.getData().length && i >=0 && c < 10)
                    {
                        message.add(s.getData()[c]);
                        c++;
                        i--;
                    }
                    ref = i;
                };break;
            }
    }
            // idon't need to use this method (Excess code)
    public MessageFolder[] displaymessage()throws IOException
    {
        int i = 0;
        MessageFolder[] s = new MessageFolder[message.size()];
        DNode u = message.getHeader();
        while(i < s.length)
        {
            u = u.getNext();
            s[i] = new MessageFolder();
            s[i].findMessageComponent((File)u.getData());
            i++;
        }
        return s;
    }
            //read specific message
    /*public MessageFolder readMessage(String name, MessageFolder[] m)
    {
    SData s = new SData(m,name);
    s.setCompareKey(6);
    s.sortList();
    Object o = s.binSearch();
    return (MessageFolder)o;//??????????????????????????????????????????????????????????????????????????/
    }*/
        //(Excess code)
    public MessageFolder readMessage(String name)
    {
        SData s = new SData();
        s.copyList(this.getMessage(), name);
        s.setCompareKey(6);
        s.sortList();
        Object o = s.binSearch();
        return (MessageFolder)o;//??????????????????????????????????????????????????????????????????????????/
    }
    /**
     * I use this method to read message data from message list which loaded in program
     * @param s message list which contains ten loaded messages
     * @param messageSubject message subject which appear to user
     * @return requested folder if it is found else returns null
     */
    public MessageFolder getMessageBySubject(MyDList s,String messageSubject)
    {
        SData sms = new SData();
        sms.copyList(s, messageSubject);
        sms.setCompareKey(10);
        sms.sortList();
        Object o = sms.binSearch();
        if(o != null)
        {
            DNode v = (DNode)o;
            return(MessageFolder)v.getData();
        }
        else
            return null;
    }
                                                //(Excess code)
/*public MessageFolder readMessageBySubject(String messageSubject, String folderName) throws IOException
    {
    JFileChooser chooser = new JFileChooser();
    FileSystemView v = chooser.getFileSystemView();
    File f = v.getChild(this.getUser().getFolders().getMyDir().getMyFile(), folderName);
    File sms = v.getChild(f, messageSubject);
    MessageFolder requestedMessage = new MessageFolder();
    requestedMessage.findMessageComponent(sms);
    return requestedMessage;
    }*/

                            //(Excess code)
    /*public void deleteMessage(String name,MessageFolder[] m)
    {
    SData s = new SData(m, name);
    s.setCompareKey(6);
    s.sortList();
    Object o = s.binSearch();
    if(o != null)
    {
    MessageFolder ms = (MessageFolder)o;
    ProjectFile f = new ProjectFile(ms.getMessFolder().getMyFile());
    f.deleteFile();
    }
    }*/
    /*
     * This method is used to send message or copy sent message to parent folder
     * parent folder such as temp folder , sent folder , inbox folder
     * @param parent such as temp folder , sent folder , inbox folder
     * @param text mwssage text
     * @param attach message attachments
     * @param s message informations(such that name, subject, sender ........)
     * @throws java.io.IOException

    public void sendMessage(File parent, String text, Attachment attach, Message s) throws IOException {
        MessageFolder m = new MessageFolder(parent);
        m.setAttach(attach);
        m.setSms(s);
        m.getSms().setName(m.getMessFolder().getMyFile().getName());
        m.moveTo();
        m.writeFileText(text);
        m.writeMessageInfo();
    }
    */
    /**
     * This method is used to send same message to multiple users
     * by take array os receivers and return array of messages each message with different receiver
     * @param messageSubject subject of message
     * @param receivers array of receivers
     * @return array of messages each message with different receiver
     * @throws java.io.IOException
     */
    public Message[] makeMultipleMessages(String messageSubject,String[]receivers)throws IOException
    {
        Message[] sms = new Message[receivers.length];
        for(int i=0;i<sms.length;i++)
        {
            sms[i] = new Message();
            sms[i].setSubject(messageSubject);
            sms[i].setReceiver(receivers[i]);
            sms[i].setSender(this.getUser().getUserAccount().getUserName()+"@gomail.com");
        }
        return sms;
    }
    /**
     * This method is used to send message or copy sent message to parent folder
     * @param parent parent folder such as temp folder , sent folder , inbox folder
     * @param text message text
     * @param attach message attachments
     * @param s array of messages which each element contains message informations(such that name, subject, sender ........)
     * this array of message is resulting from makeMultipleMessages(String messageSubject,String[]receivers) method
     * @throws java.io.IOException
     */
    public void sendMultipleMessages(File parent,String text,Attachment attach,Message[] s) throws IOException
    {
        for(int i=0;i<s.length;i++)
        {
            MessageFolder m = new MessageFolder(parent);
            m.setAttach(attach);
            m.setSms(s[i]);
            m.getSms().setName(m.getMessFolder().getMyFile().getName());
            m.moveTo();
            m.writeFileText(text);
            m.writeMessageInfo();
        }
    }
    /**
     * This method is used to checks this message is realized subject filters data or not
     * @param m reference or object of type message folder
     * @return result of type integer
     * returns 1 if this message is filters and trasfer to it correct filter folder
     * returns 0 if there are no filters on it
     * @throws java.io.IOException
     */
    public int filterBySubject(MessageFolder m) throws IOException
    {
        SData search = new SData();
        search.copyList(filterList, m.getSms().getSubject());
        search.setCompareKey(8);
        search.sortList();
        Object o = search.binSearch();
        if(o != null)
        {
             DNode w = (DNode)o;
             Filter f = (Filter)w.getData();
             String n = f.getDirectionFolder();     //folderName
             JFileChooser chooser = new JFileChooser();
             FileSystemView v = chooser.getFileSystemView();
             File folderRef = v.getChild(user.getFolders().getMyDir().getMyFile(), n);
             ProjectFile q = new ProjectFile(folderRef,m.getSms().getName());
             q.getMyFile().mkdir();
             q.copy(m.getMessFolder().getMyFile());
             m.getMessFolder().deleteFile();
             return 1;
        }
        else
            return 0;
    }
    /**
     * This method is used to checks this message is realized sender filters data or not
     * @param m reference or object of type message folder
     * @return result of type integer
     * returns 1 if this message is filters and trasfer to it correct filter folder
     * returns 0 if there are no filters on it
     * @throws java.io.IOException
     */
    public int filterBySender(MessageFolder m) throws IOException
    {
        SData search = new SData();
        search.copyList(filterList, m.getSms().getSender());
        search.setCompareKey(9);
        search.sortList();
        Object o = search.binSearch();
        if(o != null)
        {
             DNode w = (DNode)o;
             Filter f = (Filter)w.getData();
             String n = f.getDirectionFolder();
             JFileChooser chooser = new JFileChooser();
             FileSystemView v = chooser.getFileSystemView();
             File folderRef = v.getChild(user.getFolders().getMyDir().getMyFile(), n);
             ProjectFile q = new ProjectFile(folderRef,m.getSms().getName());
             q.getMyFile().mkdir();
             q.copy(m.getMessFolder().getMyFile());
             m.getMessFolder().deleteFile();
             return 1;
        }
        else
            return 0;
    }
    /**
     * This method is used to read user mail contact list from contact file
     * and put them to contact list
     * @param f contact file
     * @throws java.io.IOException
     */
    public void readContactData(File f)throws IOException
    {
        BufferedReader in = new BufferedReader(new FileReader(f));
        String line = "";
        String[]s ;
        while((line = in.readLine()) != null)
        {
            s = line.split(",");
            Contacts cont = new Contacts();
            cont.setContactData(s);
            contactsList.add(cont);
        }
        in.close();
    }
    /**
     *  This method is used to write contact data
     * @throws java.io.IOException
     */
    public void writeContactFile()throws IOException
    {
        BufferedWriter out = new BufferedWriter(new FileWriter(this.getUser().getFolders().getContactsFile().getMyFile()));
        DNode u = contactsList.getHeader();
        Contacts v;
        int i = 0;
        while( i < contactsList.getSize()&& u.getNext()!= contactsList.getTrialer())
        {
            String line = "";
            u = u.getNext();
            v = (Contacts)u.getData();
            line = (v.getName()+",");
            SingleNode s = v.getMails().getHead();
            for(int j=0; j < v.getMails().getSize()&& s!=null ;j++)
            {
                line += (s.getData().toString()+",");
                s = s.getNext();
            }
            out.write(line+"\n");
            i++;
        }
        out.close();
    }
    /**
     *  This method is used to read filters data which put by user
     * @param f filter file
     * @throws java.io.IOException
     */
    public void readFilterData(File f)throws IOException
    {
        BufferedReader in = new BufferedReader(new FileReader(f));
        String line = "";
        String[]s ;
        while((line = in.readLine()) != null)
        {
            s = line.split(",");
            Filter cont = new Filter();
            cont.setAllFilterData(s);
            filterList.add(cont);
        }
        in.close();
    }
    /**
     *  This method is used to write filter data i use it when user exist from server
     * @throws java.io.IOException
     */
    public void writeFilterFile()throws IOException
    {
        BufferedWriter out = new BufferedWriter(new FileWriter(this.getUser().getFolders().getFilter().getMyFile()));
        DNode u = filterList.getHeader();
        Filter v;
        int i = 0;
        while(u.getNext()!= filterList.getTrialer() && i < filterList.size())
        {
            u = u.getNext();
            v = (Filter)u.getData();
            String line = v.getSubject()+","+v.getSender()+","+v.getDirectionFolder();
            out.write(line+"\n");
            i++;
        }
        out.close();
    }
    /**
     *  This method is used to download attachment from message to any path
     * @param downloadPath path of location where message will be downloaded
     * @param source message folder
     * @throws java.io.IOException
     */
    public void downloadAttachment(String downloadPath,File source) throws IOException
    {
        ProjectFile f = new ProjectFile(downloadPath);
        f.copy(source);
    }
    /**
     *  This method is used to search messages by specified messages date
     *  and added them to messages doubly linked list
     * @param allSms all messages in specified folder
     * @param dateForm searched date
     * @throws java.text.ParseException
     */
    public void searchingByDate(MessageFolder[] allSms, String dateForm) throws ParseException
    {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-mm-dd");
        Date u = f.parse(dateForm);
        if(!message.isEmpty())
            message.clear();
        SData s = new SData(allSms, u);
        s.setCompareKey(12);
        s.sortList();
        Object o = s.binSearch();
        if(o != null)
        {
            int index = (Integer)o;     ////////////
            message.add(s.getData()[index]);
            if(index > 0)
            {
                int newIndex = index -1;
                boolean match = true;
                while(newIndex >= 0 && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSendDate().compareTo(u) == 0)
                    {
                        message.add(matchMessage);
                        newIndex--;
                    }
                    else
                        match = false;
                }
            }
            if(index < s.getData().length - 1)
            {
                int newIndex = index + 1;
                boolean match = true;
                while(newIndex <s.getData().length  && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSendDate().compareTo(u) == 0)
                    {
                        message.add(matchMessage);
                        newIndex++;
                    }
                    else
                        match = false;
                }
            }
            //if the previous two cases don't occur then message doubly linked list will be empty
        }
    }

    /**
     * This method is used to search messages by specified messages sender
     * and added them to messages doubly linked list
     * @param allSms all messages in specified folder
     * @param senderMail sender mail
     */
    public void searchingBySender(MessageFolder[] allSms, String senderMail)
    {
        if(!message.isEmpty())
            message.clear();
        SData s = new SData(allSms, senderMail);
        s.setCompareKey(13);
        s.sortList();
        Object o = s.binSearch();
        if(o != null)
        {
            int index = (Integer)o;     ////////////
            message.add(s.getData()[index]);
            if(index > 0)
            {
                int newIndex = index -1;
                boolean match = true;
                while(newIndex >= 0 && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSender().compareToIgnoreCase(senderMail) == 0)
                    {
                        message.add(matchMessage);
                        newIndex--;
                    }
                    else
                        match = false;
                }
            }
            if(index < s.getData().length - 1)
            {
                int newIndex = index + 1;
                boolean match = true;
                while(newIndex <s.getData().length  && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSender().compareToIgnoreCase(senderMail) == 0)
                    {
                        message.add(matchMessage);
                        newIndex++;
                    }
                    else
                        match = false;
                }
            }
            //if the previous two cases don't occur then message doubly linked list will be empty
        }
    }
    /**
     * This method is used to search messages by specified messages subject
     * and added them to messages doubly linked list
     * @param allSms all messages in specified folder
     * @param messageSubject specified message subject
     */
    public void searchingBySubject(MessageFolder[] allSms, String messageSubject)
    {
        if(!message.isEmpty())
            message.clear();
        SData s = new SData(allSms, messageSubject);
        s.setCompareKey(14);
        s.sortList();
        Object o = s.binSearch();
        if(o != null)
        {
            int index = (Integer)o;     ////////////
            message.add(s.getData()[index]);
            if(index > 0)
            {
                int newIndex = index -1;
                boolean match = true;
                while(newIndex >= 0 && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSubject().compareToIgnoreCase(messageSubject) == 0)
                    {
                        message.add(matchMessage);
                        newIndex--;
                    }
                    else
                        match = false;
                }
            }
            if(index < s.getData().length - 1)
            {
                int newIndex = index + 1;
                boolean match = true;
                while(newIndex <s.getData().length  && match)
                {
                    MessageFolder matchMessage = (MessageFolder)s.getData()[newIndex];
                    if(matchMessage.getSms().getSubject().compareToIgnoreCase(messageSubject) == 0)
                    {
                        message.add(matchMessage);
                        newIndex++;
                    }
                    else
                        match = false;
                }
            }
            //if the previous two cases don't occur then message doubly linked list will be empty
        }
    }
    /**
     * This method is used to sort messages by senders
     * @param allSms all messages in specified folder
     * @return sorted array according to senders
     */
    public MessageFolder[] sortingBySender(MessageFolder[] allSms)
    {
        if(!message.isEmpty())
            message.clear();
        SData s = new SData();
        s.setData(allSms);
        s.setCompareKey(13);        //sorting according to sender
        s.sortList();
        MessageFolder[]messageSortedBySender = new MessageFolder[allSms.length];
        for(int i=0; i < messageSortedBySender.length ;i++)
        {
            messageSortedBySender[i] = (MessageFolder)s.getData()[i];
        }
        return messageSortedBySender;  //return array of MessageFolder then i will use this arrray to load messages into doubly linked list
    }
     /**
     * This method is used to sort messages by subject
     * @param allSms all messages in specified folder
     * @return sorted array according to subject
     */
    public MessageFolder[] sortingBySubject(MessageFolder[] allSms)
    {
        if(!message.isEmpty())
            message.clear();
        SData s = new SData();
        s.setData(allSms);
        s.setCompareKey(14);        //sorting according to sender
        s.sortList();
        MessageFolder[]messageSortedBySubject = new MessageFolder[allSms.length];
        for(int i=0; i < messageSortedBySubject.length ;i++)
        {
            messageSortedBySubject[i] = (MessageFolder)s.getData()[i];
        }
        return messageSortedBySubject;  //return array of MessageFolder then i will use this arrray to load messages into doubly linked list
    }
     /**
     * This method is used to sort messages by attachment
     * checks whether message contains attachment or not
     * @param allSms all messages in specified folder
     * @return sorted array according to contain attachments or not
     */
    public MessageFolder[] sortingByAttachment2(MessageFolder[] allSms) throws Exception
    {
        MessageFolder[] sortedMessages = new MessageFolder[allSms.length];
        MyQueue s = new MyQueue();
        int c = 0;
        for(int i=0;i<allSms.length;i++)
        {
            File[] f = allSms[i].getAttachFolder().getMyFile().listFiles();
            if(f.length != 0)
            {
                sortedMessages[c] = allSms[i];
                c++;
            }
            else
            {
                s.enqueue(allSms[i]);
            }
        }
        for(int i =0;i<s.getSize();i++)
        {
            sortedMessages[c] = (MessageFolder)s.dequeue();
            c++;
        }
        return sortedMessages;
    }

}
